/**
 * Created by Administrator on 2016/12/23.
 */
// 绘图环境配置
let mainCanvas; // 获取canvas标签的dom节点
let mainctx; // canvas标签的二维渲染上下文
let mainCanvasWidth; // canvas容器的宽度
let mainCanvasHeight; // canvas容器的高度

let imgSrc = {}; // 所有图片资源
let fishArr = []; // 鱼群
let bulletArr = []; // 子弹集合
let coinArr = []; // 硬币集合
let coinTextArr = []; //金币数集合
let cannonType = 1; // 炮筒编号
let cannonRotate = 0; // 炮筒角度

let score = 0; // 游戏成绩
let energyNum = 0; //能量条
let mouseDownType;
let isAddEnergy = 1; // 能量当前的状态（默认为蓄能）

let bgm;
let bgm_coin;

// 图片加载
function load(arr, breakFun) {
  let iNow = 0;
  for (let i = 0; i < arr.length; i++) {
    let img = new Image();
    img.onload = function () {
      iNow++;
      if (iNow >= arr.length) {
        breakFun();
      }
    };
    img.src = arr[i].src;
    let name = arr[i].name;
    imgSrc[name] = img;
  }
}

// 当资源已加载时被触发
window.onload = function () {
  // 获取游戏音频标签的dom节点
  bgm = document.getElementById("bgmGame");
  // 获取硬币音频标签的dom节点
  bgm_coin = document.getElementById("bgmCoin");
  // 设置游戏音频的音量
  bgm.volume = 0.5;
  // 初始化成绩
  if (!localStorage.fishing_score) {
    // 如果本地存储中没有分数，则默认为1000并存入本地存储
    localStorage.fishing_score = 1000;
  }
  // 将本地存储中的分数加工成整数
  score = parseInt(localStorage.fishing_score);
  // 初始化能量条
  if (!localStorage.fishing_energyNum) {
    // 如果本地存储中没有能量条进度数据，则默认为0,并存入本地存储
    localStorage.fishing_energyNum = 0;
  }
  // 将本地存储中的能量条进度数据加工成整数
  energyNum = parseInt(localStorage.fishing_energyNum);
  // 如果本地存储中没有能量条的蓄能状态
  if (!localStorage.fishing_isAddEnergy) {
    // 则设置默认值为蓄能状态
    localStorage.fishing_isAddEnergy = 1;
  }
  // 将能量条数状态加工成整数并保存到本地存储中
  isAddEnergy = parseInt(localStorage.fishing_isAddEnergy);

  // 调用加载图片资源的方法
  load(imgSrcArr, function () {
    // 获取显示加载状态的dom节点并隐藏它
    document.getElementById("loading").style.display = "none";
    // 获取开始按钮容器的dom节点并显示它
    document.getElementById("start").style.display = "block";
    // 获取开始按钮的dom节点
    let startButton = document.getElementById("startButton");
    // 给开始按钮绑定点击事件
    startButton.addEventListener("click", function () {
      // 获取游戏主容器的dom节点并显示它
      document.getElementById("mainCanvas").style.display = "block";
      // 获取开始页面的dom节点并隐藏它
      document.getElementById("startPage").style.display = "none";
      // 调用游戏开始的方法
      start();
      addEvent();
    });
  });
};

//游戏开始
function start() {
  // 计时表
  let iNow = 0;
  // 播放游戏音乐
  bgm.play();
  // 获取canvas标签的dom节点
  mainCanvas = document.getElementById("mainCanvas");
  // 建立一个 CanvasRenderingContext2D 二维渲染上下文
  mainctx = mainCanvas.getContext("2d");
  // 创建定时循环器
  setInterval(function () {
    // 更新画面属性
    mainCanvasWidth = mainCanvas.offsetWidth;
    mainCanvasHeight = mainCanvas.offsetHeight;
    // 设置画布宽高
    mainCanvas.setAttribute("height", mainCanvasHeight);
    mainCanvas.setAttribute("width", mainCanvasWidth);
    // 清空画布
    mainctx.clearRect(0, 0, mainCanvasWidth, mainCanvasHeight);
    // 使用栈保存当前的绘画样式状态，你可以使用 restore() 恢复任何改变
    mainctx.save();
    // 描绘背景
    mainctx.drawImage(imgSrc["bg"], 0, 0, mainCanvasWidth, mainCanvasHeight);
    // 调用绘制鱼群的方法
    drawFish();
    // 调用绘制子弹的方法
    drawBullet();
    // 调用绘制金币数字的方法
    drawCoinText();
    // 调用绘制硬币的方法
    drawCoin();
    // 调用绘制面板的方法
    drawBar();
    // 恢复到最近的绘制样式状态，此状态是通过 save() 保存到”状态栈“中最新的元素
    mainctx.restore();
    // 如果达到规定时间
    if (iNow % frequency == 0) {
      // 计时表归零
      iNow = 0;
      // 调用添加鱼儿的方法
      addFish();
    }
    // 更新计时表
    iNow++;
  }, 30);
}

// 添加鱼儿的方法
function addFish() {
  // 获取一个随机数
  let random = Math.random();
  // 鱼类型
  let fishType = 1;
  // 循环遍历所有鱼类型
  for (let i = 1; i <= flashAtt_length; i++) {
    // 拿到当前鱼类型名称
    let name = "fish" + i;
    // 如果满足出现条件
    if (random <= flashAtt[name].pro) {
      // 更新鱼类型
      fishType = i;
      // 结束循环
      break;
    }
  }
  // 预设方向（随机选择）
  let start = Math.random();
  // 将预设随机方向的鱼添加到鱼群列表中
  if (start > 0.5) {
    // 将随机选择的鱼添加到鱼群列表中
    fishArr.push({
      // 随机的鱼类型
      type: "fish" + fishType,
      // 左侧方向
      x: -40,
      // 纵坐标
      y: Math.random() * (mainCanvasHeight * 0.5) + mainCanvasHeight * 0.25,
      // 旋转弧度
      rotate: Math.random() * 1.2 - 0.6,
      frame: 0,
      //
      isLive: true,
    });
  } else {
    fishArr.push({
      type: "fish" + fishType,
      x: mainCanvasWidth + 40,
      y: Math.random() * (mainCanvasHeight * 0.5) + mainCanvasHeight * 0.25,
      rotate: Math.random() * 1.2 - 0.6 + Math.PI,
      frame: 0,
      isLive: true,
    });
  }
}

// 绘制鱼群的方法
function drawFish() {
  // 遍历鱼群
  for (let i = 0; i < fishArr.length; i++) {
    // 如果鱼越界
    if (
      fishArr[i].x < -150 ||
      fishArr[i].x > mainCanvasWidth + 150 ||
      fishArr[i].y < -150 ||
      fishArr[i].y > mainCanvasHeight + 150
    ) {
      // 移除鱼群列表中对应鱼
      fishArr.splice(i, 1);
      i--;
      // 跳过本次循环
      continue;
    }
    // 拿到当前鱼类型
    let name = fishArr[i].type;
    // 用栈保存当前的绘画样式状态，你可以使用 restore() 恢复任何改变
    mainctx.save();
    // 通过在网格中移动 canvas 和 canvas 原点 x 水平方向、原点 y 垂直方向，添加平移变换
    mainctx.translate(fishArr[i].x, fishArr[i].y);
    // 在变换矩阵中增加旋转，角度变量表示一个顺时针旋转角度并且用弧度表示
    mainctx.rotate(fishArr[i].rotate);
    // 通过在网格中移动 canvas 和 canvas 原点 x 水平方向、原点 y 垂直方向，添加平移变换
    mainctx.translate(
      -flashAtt[fishArr[i].type].width / 2,
      -flashAtt[fishArr[i].type].height / 2
    );

    if (fishArr[i].rotate > 0.5 * Math.PI) mainctx.scale(1, -1);
    mainctx.drawImage(
      imgSrc[name],
      0,
      flashAtt[name].height * Math.floor(fishArr[i].frame),
      flashAtt[name].width,
      flashAtt[name].height,
      0,
      0,
      flashAtt[name].width,
      flashAtt[name].height
    );
    mainctx.restore();
    // 修改参数
    fishArr[i].frame += 0.25;
    if (fishArr[i].isLive) {
      if (fishArr[i].frame >= flashAtt[name].sumFrame - 4) fishArr[i].frame = 0;
      fishArr[i].x += flashAtt[name].speed * Math.cos(fishArr[i].rotate);
      fishArr[i].y += flashAtt[name].speed * Math.sin(fishArr[i].rotate);
      fishArr[i].rotate += Math.random() * 0.02 - 0.01;
    } else {
      // 死亡
      if (fishArr[i].frame >= flashAtt[name].sumFrame) {
        addCoinText(fishArr[i].x, fishArr[i].y, flashAtt[name].cost); // 添加金币数字
        addCoin(fishArr[i].x, fishArr[i].y, flashAtt[name].cost); // 添加硬币
        fishArr.splice(i, 1);
        i--;
      }
    }
  }
}

// 添加子弹的方法
function addBullet() {
  bulletArr.push({
    type: "bullet" + cannonType,
    x: mainCanvasWidth / 2 + 45,
    y: mainCanvasHeight - barHeight / 2,
    rotate: -0.5 * Math.PI + cannonRotate,
  });
}

// 绘制子弹的方法
function drawBullet() {
  // 遍历子弹列表
  for (let i = 0; i < bulletArr.length; i++) {
    let isDraw = true;
    // 如果当前子弹越过舞台边界
    if (
      bulletArr[i].x < -15 ||
      bulletArr[i].x > mainCanvasWidth + 15 ||
      bulletArr[i].y < -15 ||
      bulletArr[i].y > mainCanvasHeight + 15
    ) {
      isDraw = false;
    }
    // 碰撞检测
    if (
      isDraw &&
      bulletArr[i].x > 20 &&
      bulletArr[i].x < mainCanvasWidth - 20 &&
      bulletArr[i].y > 20 &&
      bulletArr[i].y < mainCanvasHeight - barHeight - 30
    ) {
      let bulletX = bulletArr[i].x;
      let bulletY = bulletArr[i].y;
      for (let j = 0; j < fishArr.length; j++) {
        if (
          fishArr[j].x < 0 ||
          fishArr[j].x > mainCanvasWidth ||
          fishArr[j].y < 0 ||
          fishArr[j].y > mainCanvasHeight - barHeight - 10 ||
          fishArr[j].isLive == false
        )
          continue;
        let relationship = getRelationship(
          bulletX,
          bulletY,
          fishArr[j].x,
          fishArr[j].y
        );
        if (relationship.d <= bulletAtt[bulletArr[i].type].range) {
          fishArr[j].frame = flashAtt[fishArr[j].type].sumFrame - 4;
          fishArr[j].isLive = false;
          isDraw = false;
          //金币音效
          bgm_coin.currentTime = 0.0;
          bgm_coin.play();
        }
      }
    }
    if (!isDraw) {
      bulletArr.splice(i, 1);
      i--;
      continue;
    }
    let name = bulletArr[i].type;
    mainctx.save();
    mainctx.translate(bulletArr[i].x, bulletArr[i].y);
    mainctx.rotate(bulletArr[i].rotate + 0.5 * Math.PI);
    mainctx.translate(-bulletAtt[name].width / 2, -bulletAtt[name].height / 2);
    if (bulletArr[i].rotate > 0.5 * Math.PI) mainctx.scale(1, -1);
    mainctx.drawImage(
      imgSrc[name],
      0,
      0,
      bulletAtt[name].width,
      bulletAtt[name].height,
      0,
      0,
      bulletAtt[name].width,
      bulletAtt[name].height
    );
    mainctx.restore();
    //修改参数
    bulletArr[i].x += bulletAtt[name].speed * Math.cos(bulletArr[i].rotate);
    bulletArr[i].y += bulletAtt[name].speed * Math.sin(bulletArr[i].rotate);
  }
}

// 添加金币数字的方法
function addCoinText(x, y, num) {
  coinTextArr.push({
    x: x,
    y: y,
    num: num,
    frame: 0,
  });
}

// 绘制金币数字的方法
function drawCoinText() {
  for (let i = 0; i < coinTextArr.length; i++) {
    let num = coinTextArr[i].num;
    mainctx.save();
    mainctx.translate(
      coinTextArr[i].x - coinTextWidth / 2,
      coinTextArr[i].y - coinTextHeight / 2
    );
    mainctx.drawImage(
      imgSrc["coinText"],
      10 * coinTextWidth,
      0,
      coinTextWidth,
      coinTextHeight,
      0,
      0,
      coinTextWidth,
      coinTextHeight
    );
    let iNow = 1;
    let canDraw = false;
    for (let j = flashCost_maxLength - 1; j >= 0; j--) {
      let numbit = Math.floor(num / Math.pow(10, j));
      if (numbit) canDraw = true;
      if (canDraw) {
        mainctx.drawImage(
          imgSrc["coinText"],
          numbit * coinTextWidth,
          0,
          coinTextWidth,
          coinTextHeight,
          coinTextWidth * iNow,
          0,
          coinTextWidth,
          coinTextHeight
        );
        iNow++;
      }
      num %= Math.pow(10, j);
    }
    mainctx.restore();
    coinTextArr[i].frame++;
    coinTextArr[i].y -= coinTextSpeed;
    if (coinTextArr[i].frame > coinTime * coinSpeed) {
      coinTextArr.splice(i, 1);
      i--;
    }
  }
}

// 添加硬币的方法
function addCoin(x, y, num) {
  let relationship = getRelationship(
    (mainCanvasWidth - barWidth) / 2 + 80,
    mainCanvasHeight - barHeight + 20,
    x,
    y
  );
  coinArr.push({
    x: x,
    y: y,
    dx: relationship.dx / (coinTime * coinSpeed),
    dy: relationship.dy / (coinTime * coinSpeed),
    num: num,
    frame: 0,
  });
}

// 绘制硬币的方法
function drawCoin() {
  for (let i = 0; i < coinArr.length; i++) {
    mainctx.save();
    mainctx.translate(coinArr[i].x - coinWidth, coinArr[i].y - coinHeight);
    if (coinArr[i].num <= coinLim)
      mainctx.drawImage(
        imgSrc["coinAni1"],
        0,
        coinHeight * Math.floor(coinArr[i].frame),
        coinWidth,
        coinHeight,
        0,
        0,
        coinWidth,
        coinHeight
      );
    //小硬币
    else
      mainctx.drawImage(
        imgSrc["coinAni2"],
        0,
        coinHeight * Math.floor(coinArr[i].frame),
        coinWidth,
        coinHeight,
        0,
        0,
        coinWidth,
        coinHeight
      ); //大硬币
    mainctx.restore();
    coinArr[i].frame += 1 / coinSpeed;
    coinArr[i].x += coinArr[i].dx;
    coinArr[i].y += coinArr[i].dy;
    if (coinArr[i].frame > coinTime) {
      changeScore(coinArr[i].num);
      changeEnergy(coinArr[i].num);
      coinArr.splice(i, 1);
      i--;
    }
  }
}
// 绘制面板的方法
function drawBar() {
  // 用栈保存当前的绘画样式状态，你可以使用 restore() 恢复任何改变
  mainctx.save();
  // 面板底部，通过在网格中移动 canvas 和 canvas 原点 x 水平方向、原点 y 垂直方向，添加平移变换
  mainctx.translate(
    // （画布容器宽度 - 底部操作栏宽度）/ 2
    (mainCanvasWidth - barWidth) / 2,
    // 画布容器高度 - 底部操作栏高度 + 3
    mainCanvasHeight - barHeight + 3
  );
  // 绘制指定的图片
  mainctx.drawImage(imgSrc["bottom-bar"], 0, 0, barWidth, barHeight);
  // 游戏成绩
  let num = score >= 0 ? score : 0;
  // 循环遍历6次(根据分数最大数)
  for (let i = 5; i >= 0; i--) {
    // 数字分位处理（获取分数的个位数）
    let numBit = Math.floor(num % 10);
    // 将当前分数除以10
    num = Math.floor(num / 10);
    // 绘制指定的图片
    mainctx.drawImage(
      // 绘制到上下文的元素。允许任何的 canvas 图像源
      imgSrc["bottom-num"],
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
      scoreHeight * (9 - numBit),
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
      scoreWidth,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
      scoreHeight,
      // image的左上角在目标canvas上 X 轴坐标（左侧偏移量 + 位数索引 * (裁剪图片宽度 + 3)）
      20 + i * (scoreWidth + 3),
      // image的左上角在目标canvas上 Y 轴坐标
      44,
      // image在目标canvas上绘制的宽度
      scoreWidth,
      // image在目标canvas上绘制的高度
      scoreHeight
    );
  }
  // 如果用户当前按下炮筒加宽按钮
  if (mouseDownType === "+") {
    // 绘制指定的加宽激活按钮图片
    mainctx.drawImage(
      // 绘制到上下文的元素（加号激活状态按钮图片）
      imgSrc["cannon_plus_down"],
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
      cannonWidth,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
      cannonHeight,
      // image的左上角在目标canvas上 X 轴坐标
      162,
      // image的左上角在目标canvas上 Y 轴坐标
      45,
      // image在目标canvas上绘制的宽度
      cannonWidth - 15,
      // image在目标canvas上绘制的高度
      cannonHeight - 8
    ); //加号
  } else {
    // 绘制指定的加宽按钮图片
    mainctx.drawImage(
      // 绘制到上下文的元素（加号按钮图片）
      imgSrc["cannon_plus"],
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
      cannonWidth,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
      cannonHeight,
      // image的左上角在目标canvas上 X 轴坐标
      162,
      // image的左上角在目标canvas上 Y 轴坐标
      45,
      // image在目标canvas上绘制的宽度
      cannonWidth - 15,
      // image在目标canvas上绘制的高度
      cannonHeight - 8
    );
  }
  // 如果用户当前按下炮筒减宽按钮
  if (mouseDownType === "-") {
    // 绘制指定的减宽激活按钮图片
    mainctx.drawImage(
      // 绘制到上下文的元素（减号激活状态按钮图片）
      imgSrc["cannon_minus_down"],
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
      cannonWidth,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
      cannonHeight,
      // image的左上角在目标canvas上 X 轴坐标
      188,
      // image的左上角在目标canvas上 Y 轴坐标
      45,
      // image在目标canvas上绘制的宽度
      cannonWidth - 15,
      // image在目标canvas上绘制的高度
      cannonHeight - 8
    ); //减号
  } else {
    // 绘制指定的减宽按钮图片
    mainctx.drawImage(
      // 绘制到上下文的元素（减号按钮图片）
      imgSrc["cannon_minus"],
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
      0,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
      cannonWidth,
      // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
      cannonHeight,
      // image的左上角在目标canvas上 X 轴坐标
      188,
      // image的左上角在目标canvas上 Y 轴坐标
      45,
      // image在目标canvas上绘制的宽度
      cannonWidth - 15,
      // image在目标canvas上绘制的高度
      cannonHeight - 8
    ); //减号
  }
  // 用栈保存当前的绘画样式状态，你可以使用 restore() 恢复任何改变
  mainctx.save();
  // 绘制大炮
  // 设置炮筒位置
  mainctx.translate(barWidth / 2 + 45, barHeight / 2);
  // 设置炮筒角度
  mainctx.rotate(cannonRotate);
  // 填充炮筒底座颜色
  mainctx.fillStyle = "#789456";
  // 绘制炮筒底座矩形
  mainctx.fillRect(0, 0, 10, 10);
  // 拿到当前炮筒名称
  let cannonName = "cannon" + cannonType;
  // 设置炮筒底座位置
  mainctx.translate(
    // 当前炮筒宽度 / 2
    -cannonAtt[cannonName].width / 2,
    // 当前炮筒高度 / 2
    -cannonAtt[cannonName].height / 2
  );
  // 绘制炮筒
  mainctx.drawImage(
    // 绘制到上下文的元素（对应炮筒图片）
    imgSrc[cannonName],
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
    0,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
    0,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
    cannonAtt[cannonName].width,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
    cannonAtt[cannonName].height,
    // image的左上角在目标canvas上 X 轴坐标
    0,
    // image的左上角在目标canvas上 Y 轴坐标
    0,
    // image在目标canvas上绘制的宽度
    cannonAtt[cannonName].width,
    // image在目标canvas上绘制的高度
    cannonAtt[cannonName].height
  );
  // 将 canvas 恢复到最近的保存状态的方法
  mainctx.restore();
  // 绘制能量条
  // 如果能量条当前是放能状态
  if (!isAddEnergy) {
    // 调用修改能量条的方法
    changeEnergy(0 - energySpeed);
  } else {
    // 调用修改能量条的方法
    changeEnergy(0.05);
  }
  // 能量条进度百分比（当前进度 / 最大临界值）
  let proportion = energyNum / energyMax;
  // 用栈保存当前的绘画样式状态，你可以使用 restore() 恢复任何改变
  mainctx.save();
  // 设置能量条位置
  mainctx.translate(542, 44);
  // 绘制能量条
  mainctx.drawImage(
    // 绘制到上下文的元素（减号按钮图片）
    imgSrc["energy-bar"],
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 X 轴坐标
    0,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的左上角 Y 轴坐标
    0,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的宽度
    energyWidth * proportion,
    // 需要绘制到目标上下文中的，image的矩形（裁剪）选择框的高度
    energyHeight,
    // image的左上角在目标canvas上 X 轴坐标
    0,
    // image的左上角在目标canvas上 Y 轴坐标
    0,
    // image在目标canvas上绘制的宽度
    energyWidth * proportion,
    // image在目标canvas上绘制的高度
    energyHeight
  );
  // 将 canvas 恢复到最近的保存状态的方法
  mainctx.restore();
  // 将 canvas 恢复到最近的保存状态的方法
  mainctx.restore();
}

// 得到两点间的关系
// 以p1为基准
function getRelationship(p1X, p1Y, p2X, p2Y) {
  let dx = p1X - p2X;
  let dy = p1Y - p2Y;
  let d = Math.sqrt(dx * dx + dy * dy);
  let rotate = Math.acos(dx / d);
  return {
    dx: dx,
    dy: dy,
    d: d,
    rotate: rotate,
  };
}

// 修改成绩的方法
function changeScore(num) {
  score += num;
  localStorage.fishing_score = score;
}

// 修改能量条的方法
function changeEnergy(num) {
  // 如果是蓄能状态并且进度大于0 或者 是放能状态并且进度小于0 ，则更新能量条进度
  if ((isAddEnergy && num > 0) || (!isAddEnergy && num < 0)) energyNum += num;
  // 如果能量条进度大于最大临界值
  if (energyNum > energyMax) {
    // 将能量条进度更新到最大临界值
    energyNum = energyMax;
    // 调用发放奖励的方法
    reward();
    // 将能量条的状态设置为放能状态
    isAddEnergy = 0;
  }
  // 如果能量条进度小于0
  if (energyNum < 0) {
    // 将能量条进度设置为0
    energyNum = 0;
    // 将能量条的状态设置为蓄能状态
    isAddEnergy = 1;
  }
  // 将能量条进度保存到本地存储中
  localStorage.fishing_energyNum = parseInt(energyNum);
  // 将能量条状态保存到本地存储中
  localStorage.fishing_isAddEnergy = isAddEnergy;
}

// 发放奖励的方法
function reward() {
  // 放鱼
  for (let i = 0; i < rewardFish; i++) addFish();
}

// 绑定事件
function addEvent() {
  // 给画布容器绑定触摸点击事件
  mainCanvas.addEventListener("mousedown", function (ev) {
    let mouseX = ev.clientX;
    let mouseY = ev.clientY;
    //按键判断
    let startX = (mainCanvasWidth - barWidth) / 2;
    let startY = mainCanvasHeight - barHeight + 3;
    let testCannonX = mouseX - startX - 162;
    let testCannonY = mouseY - startY - 45;
    if (
      testCannonX >= 0 &&
      testCannonX <= cannonWidth - 15 &&
      testCannonY >= 0 &&
      testCannonY <= cannonHeight - 8
    ) {
      mouseDownType = "+";
      cannonType++;
    } else if (
      testCannonX >= 26 &&
      testCannonX <= cannonWidth + 11 &&
      testCannonY >= 0 &&
      testCannonY <= cannonHeight - 8
    ) {
      mouseDownType = "-";
      cannonType--;
    } else {
      //发子弹
      if (bulletAtt["bullet" + cannonType].cost <= score) {
        addBullet();
        changeScore(-bulletAtt["bullet" + cannonType].cost);
      }
    }
    if (cannonType > cannonAtt_length) cannonType = 1;
    else if (cannonType < 1) cannonType = cannonAtt_length;
  });
  mainCanvas.addEventListener("mouseup", function () {
    mouseDownType = "";
  });
  mainCanvas.addEventListener("mousemove", function (ev) {
    let mouseX = ev.clientX;
    let mouseY = ev.clientY;
    let relationship = getRelationship(
      mainCanvasWidth / 2 + 45,
      mainCanvasHeight - barHeight / 2,
      mouseX,
      mouseY
    );
    cannonRotate = -0.5 * Math.PI + relationship.rotate;
  });
}
